/**
 * Copyright (C) 2018-2020
 * All rights reserved, Designed By www.yixiang.co
 * 注意：
 * 本软件为www.yixiang.co开发研制，未经购买不得使用
 * 购买后可获得全部源代码（禁止转卖、分享、上传到码云、github等开源平台）
 * 一经发现盗用、分享等行为，将追究法律责任，后果自负
 */
package co.yixiang.modules.user.rest;

import cn.hutool.core.bean.BeanUtil;
import co.y.t.hyfPay.Config;
import co.y.t.hyfPay.HttpClient;
import co.y.t.hyfPay.Safe;
import co.yixiang.api.ApiResult;
import co.yixiang.api.YshopException;
import co.yixiang.logging.aop.log.AppLog;
import co.yixiang.common.bean.LocalUser;
import co.yixiang.common.interceptor.AuthCheck;
import co.yixiang.constant.ShopConstants;
import co.yixiang.enums.AppFromEnum;
import co.yixiang.enums.BillDetailEnum;
import co.yixiang.modules.order.dto.OrderExtendDto;
import co.yixiang.modules.shop.domain.YxSystemGroupData;
import co.yixiang.modules.shop.service.YxSystemGroupDataService;
import co.yixiang.modules.shop.service.dto.YxSystemGroupDataQueryCriteria;
import co.yixiang.modules.shop.vo.YxSystemGroupDataVo;
import co.yixiang.modules.user.domain.ShoppingPayform;
import co.yixiang.modules.user.domain.YxUser;
import co.yixiang.modules.user.param.RechargeParam;
import co.yixiang.modules.user.service.ShoppingPayformService;
import co.yixiang.modules.user.service.YxUserRechargeService;
import co.yixiang.modules.mp.service.WeixinPayService;
import co.yixiang.modules.user.service.dto.WechatUserDto;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.binarywang.wxpay.bean.order.WxPayAppOrderResult;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.order.WxPayMwebOrderResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户充值 前端控制器
 * </p>
 *
 * @author hupeng
 * @since 2020-03-01
 */
@Slf4j
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Api(value = "用户充值", tags = "用户:用户充值", description = "用户充值")
public class UserRechargeController {

    private final YxUserRechargeService userRechargeService;
    private final WeixinPayService weixinPayService;
    private final YxSystemGroupDataService systemGroupDataService;
    private final ShoppingPayformService shoppingPayformService;

    /**
     * 充值方案
     */
    @GetMapping("/recharge/index")
    @ApiOperation(value = "充值方案",notes = "充值方案",response = ApiResult.class)
    public ApiResult<Object> getWays(){
        YxSystemGroupDataQueryCriteria queryCriteria = new YxSystemGroupDataQueryCriteria();
        queryCriteria.setGroupName(ShopConstants.YSHOP_RECHARGE_PRICE_WAYS);
        List<YxSystemGroupData> yxSystemGroupDataList = systemGroupDataService.queryAll(queryCriteria);

        List<YxSystemGroupDataVo> systemGroupDataVoList = yxSystemGroupDataList.stream().map(s->{
            YxSystemGroupDataVo systemGroupDataVo = new YxSystemGroupDataVo();
            BeanUtil.copyProperties(s,systemGroupDataVo,"value");
            systemGroupDataVo.setValue(JSON.parseObject(s.getValue()));
            return systemGroupDataVo;
        }).collect(Collectors.toList());

        Map<String,Object> map = new LinkedHashMap<>();
        map.put("recharge_price_ways",systemGroupDataVoList);
        return ApiResult.ok(map);
    }

    /**
     * 公众号充值/H5充值
     */
    @AppLog(value = "公众号充值", type = 1)
    @AuthCheck
    @PostMapping("/recharge/wechat")
    @ApiOperation(value = "公众号充值/H5充值",notes = "公众号充值/H5充值",response = ApiResult.class)
    public ApiResult<Map<String,Object>> add(@Valid @RequestBody RechargeParam param){
        YxUser user = LocalUser.getUser();

        Map<String,Object> map = new LinkedHashMap<>();
        map.put("type",param.getFrom());
        YxSystemGroupData systemGroupData = systemGroupDataService.getById(param.getRecharId());
        if(systemGroupData == null) {
            throw new YshopException("充值方案不存在");
        }

        JSONObject jsonObject = JSON.parseObject(systemGroupData.getValue());
        String price = jsonObject.getString("price");
        String giveMoney =jsonObject.getString("give_price");
        String orderSn = userRechargeService.addRecharge(user,price,giveMoney);

        if(AppFromEnum.WEIXIN_H5.getValue().equals(param.getFrom())){
            WxPayMwebOrderResult result = (WxPayMwebOrderResult)weixinPayService
                    .unifyPay(orderSn,param.getFrom(), BillDetailEnum.TYPE_1.getValue(),"H5充值");
            map.put("data",result.getMwebUrl());
        }else if(AppFromEnum.ROUNTINE.getValue().equals(param.getFrom())){
            WxPayMpOrderResult wxPayMpOrderResult = (WxPayMpOrderResult)weixinPayService
                    .unifyPay(orderSn,param.getFrom(), BillDetailEnum.TYPE_1.getValue(),"小程序充值");
            Map<String,String> jsConfig = new HashMap<>();
            jsConfig.put("timeStamp",wxPayMpOrderResult.getTimeStamp());
            jsConfig.put("appId",wxPayMpOrderResult.getAppId());
            jsConfig.put("paySign",wxPayMpOrderResult.getPaySign());
            jsConfig.put("nonceStr",wxPayMpOrderResult.getNonceStr());
            jsConfig.put("package",wxPayMpOrderResult.getPackageValue());
            jsConfig.put("signType",wxPayMpOrderResult.getSignType());
            map.put("data",jsConfig);
        }else if(AppFromEnum.APP.getValue().equals(param.getFrom())){
            WxPayAppOrderResult wxPayAppOrderResult = (WxPayAppOrderResult)weixinPayService
                    .unifyPay(orderSn,param.getFrom(), BillDetailEnum.TYPE_1.getValue(),"app充值");
            Map<String,String> jsConfig = new HashMap<>();
            jsConfig.put("partnerid",wxPayAppOrderResult.getPartnerId());
            jsConfig.put("appid",wxPayAppOrderResult.getAppId());
            jsConfig.put("prepayid",wxPayAppOrderResult.getPrepayId());
            jsConfig.put("package",wxPayAppOrderResult.getPackageValue());
            jsConfig.put("noncestr",wxPayAppOrderResult.getNonceStr());
            jsConfig.put("timestamp",wxPayAppOrderResult.getTimeStamp());
            jsConfig.put("sign",wxPayAppOrderResult.getSign());
            map.put("data",jsConfig);
        }else if(AppFromEnum.HYF_H5.getValue().equals(param.getFrom())){
            BigDecimal bigDecimal = new BigDecimal(100);
            int payPrice = 0;
            String goods = "客户付款";
            map.put("status", "HYF_RECHARGE");
            String order_id = "hyf1000";
            //uid = orderInfo.getUid().intValue();
            //计算分
            //payPrice = bigDecimal.multiply(orderInfo.getPayPrice()).intValue();
            payPrice = bigDecimal.multiply(new BigDecimal("0.01")).intValue();
            ShoppingPayform pf = new ShoppingPayform();
            pf.setTotalprice(new BigDecimal(price));
            pf.setDeletestatus(false);
            pf.setUid(user.getUid());
            pf.setPayType("汇卡支付");
            pf.setPayno(orderSn+"-"+order_id+"-"+user.getUid());
            pf.setOrderId(order_id);
            pf.setPaystatus("未支付");
            shoppingPayformService.save(pf);
            //map.put("result",orderDTO);
            map.put("payMsg", "订单创建成功");

            String returnUrl = Config.returnUrl;  // 前台返回页面：以商家自己的网站为准
            String notifyUrl = Config.notifyUrl; // 后端通知页面：以商家自己的网站为准
            // POST请求参数：按签名顺序，有序存放
            TreeMap<String, String> params = new TreeMap<String, String> ();
            params.put("amount", Long.toString(payPrice)); // 金额单位为“分”
            params.put("backEndUrl", notifyUrl);
            params.put("bizType", "814"); // 商家自定义的业务类别
            params.put("frontEndUrl", returnUrl);
            params.put("goodsName", goods); // 商家自定义的货物名称，该字段不需参加签名
            params.put("hicardMerchNo", Config.merchNo);
            params.put("isT0", "1");
            //params.put("merchOrderNo", vo.getRechargeBillId()); // 商家自定义的订单号
            params.put("merchOrderNo", pf.getPayno());
            params.put("organNo", Config.organNo);
            params.put("payType", "014");
            params.put("showPage", "0"); // 固定
            params.put("version", Config.version);
            params.put("sign", Safe.sign(params)); // 签名
            params.put("subAppId", "");
            params.put("remark", "");
            params.put("transIP", ""); // 该字段不需参加签名
            params.put("reserved", ""); // 该字段不需参加签名

            // params.put("isT0", "1");

            com.alibaba.fastjson.JSONObject jo = new com.alibaba.fastjson.JSONObject();
            jo.putAll(params);

            String json = jo.toString();
            System.out.println("发送数据：" + json);
            log.info("发送数据：" + json);
            String url = "http://" + Config.payIPAddress
                    + "/hicardpay/order/create";
            String resp = HttpClient.post(json, url);
            System.out.println("返回数据：" + resp);
            log.info("返回数据：" + resp);
            com.alibaba.fastjson.JSONObject resJo = com.alibaba.fastjson.JSONObject.parseObject(resp);
            System.out.println("resJo=======" + resJo);
            log.info("resJo=======" + resJo);
            // 验证签名
            // 返回数据：{"html":"","version":"V003","sign":"5d81096366913ec56c0e4fe121ff592e","hicardMerchNo":"104401569102119","amount":"1","createTime":"2018-01-16 22:20:51","qrURL":"","merchOrderNo":"f6edc266-a0b0-4016-a235-2035d73cecb3","payType":"014","payInfo":"http://ymftest.hi-card.cn/hicardqrcode/qrCode/jsapi/Host6?orderNo=4161801160103314","respCode":"00","organNo":"12999000","respMsg":"处理成功","hicardOrderNo":"4161801160103314"}
            TreeMap<String, String>  params2 = new TreeMap<String, String> ();
            params2.put("amount", Long.toString(resJo.getLong("amount")));
            params2.put("createTime", resJo.getString("createTime"));
            params2.put("hicardMerchNo", resJo.getString("hicardMerchNo"));
            params2.put("hicardOrderNo", resJo.getString("hicardOrderNo"));
            if (resJo.containsKey("html")) {
                params2.put("html", resJo.getString("html"));
            }
            if (resJo.containsKey("isT0")) {
                params2.put("isT0", resJo.getString("isT0"));
            }
            params2.put("merchOrderNo", resJo.getString("merchOrderNo"));
            params2.put("organNo", resJo.getString("organNo"));
            params2.put("payInfo", resJo.getString("payInfo"));
            params2.put("payType", resJo.getString("payType"));
            if (resJo.containsKey("qrURL")) {
                params2.put("qrURL", resJo.getString("qrURL"));
            }
            params2.put("respCode", resJo.getString("respCode"));
            params2.put("respMsg", resJo.getString("respMsg"));
            if (resJo.containsKey("showPage")) {
                params2.put("showPage", resJo.getString("showPage"));
            }

            params2.put("version", resJo.getString("version"));
            String myRSign = Safe.sign(params2);
            String rSign = resJo.getString("sign");
		/*if (!myRSign.equals(rSign)) {
			resultMap.put("payState", "fail");
			resultMap.put("message", "签名异常，支付失败!");
			resultMap.put("payUrl", resJo.getString("payInfo"));
		} else {*/
            if ("00".equals(resJo.getString("respCode"))) {

                String payUrl = resJo.getString("payInfo");
                System.out.println("payUrl=======" + payUrl);
                map.put("payState", "success");
                map.put("mweb_url", payUrl);
                // response.sendRedirect(payUrl);
            }
        }else if(AppFromEnum.HYF_MINI.getValue().equals(param.getFrom())){
            BigDecimal bigDecimal = new BigDecimal(100);
            int payPrice = 0;
            String goods = "客户付款";
            map.put("status", "HYF_RECHARGE");
            String order_id = "hyf1000";
            //uid = orderInfo.getUid().intValue();
            //计算分
            //payPrice = bigDecimal.multiply(orderInfo.getPayPrice()).intValue();
            payPrice = bigDecimal.multiply(new BigDecimal("0.01")).intValue();
            ShoppingPayform pf = new ShoppingPayform();
            pf.setTotalprice(new BigDecimal(price));
            pf.setDeletestatus(false);
            pf.setUid(user.getUid());
            pf.setPayType("汇卡支付");
            pf.setPayno(orderSn+"-"+order_id+"-"+user.getUid());
            pf.setOrderId(order_id);
            pf.setPaystatus("未支付");
            shoppingPayformService.save(pf);
            //map.put("result",orderDTO);
            map.put("payMsg", "订单创建成功");

            WechatUserDto wechatUser = user.getWxProfile();
            String openid = wechatUser.getRoutineOpenid();
            String returnUrl = Config.returnUrl;  // 前台返回页面：以商家自己的网站为准
            String notifyUrl = Config.notifyUrl; // 后端通知页面：以商家自己的网站为准
            // POST请求参数：按签名顺序，有序存放
            TreeMap<String, String> paramss = new TreeMap<String, String>();
            paramss.put("amount", Long.toString(payPrice)); // 金额单位为“分”
            paramss.put("backEndUrl", notifyUrl);
            paramss.put("bizType", "814"); // 商家自定义的业务类别
            paramss.put("frontEndUrl", returnUrl);
            paramss.put("goodsName", goods); // 商家自定义的货物名称，该字段不需参加签名
            paramss.put("hicardMerchNo", Config.merchNo);
            paramss.put("isT0", "1");
            //params.put("merchOrderNo", vo.getRechargeBillId()); // 商家自定义的订单号
            paramss.put("merchOrderNo", pf.getPayno());
            paramss.put("openId", openid);
            paramss.put("organNo", Config.organNo);
            paramss.put("payType", "014");
            paramss.put("showPage", "0"); // 固定
            paramss.put("subAppId", Config.appid);
            paramss.put("version", Config.version);
            paramss.put("sign", Safe.sign4mini(paramss)); // 签名
            paramss.put("remark", "");
            paramss.put("transIP", ""); // 该字段不需参加签名
            paramss.put("reserved", ""); // 该字段不需参加签名

            // params.put("isT0", "1");

            com.alibaba.fastjson.JSONObject jo1 = new com.alibaba.fastjson.JSONObject();
            jo1.putAll(paramss);

            String json1 = jo1.toString();
            System.out.println("发送数据：" + json1);
            log.info("发送数据：" + json1);
            String url1 = "http://" + Config.payIPAddress
                    + "/hicardpay/order/create";
            String resp1 = HttpClient.post(json1, url1);
            System.out.println("返回数据：" + resp1);
            log.info("返回数据：" + resp1);
            com.alibaba.fastjson.JSONObject resJo1 = com.alibaba.fastjson.JSONObject.parseObject(resp1);
            System.out.println("resJo=======" + resJo1);
            log.info("resJo=======" + resJo1);
            // 验证签名
            // 返回数据：{"html":"","version":"V003","sign":"5d81096366913ec56c0e4fe121ff592e","hicardMerchNo":"104401569102119","amount":"1","createTime":"2018-01-16 22:20:51","qrURL":"","merchOrderNo":"f6edc266-a0b0-4016-a235-2035d73cecb3","payType":"014","payInfo":"http://ymftest.hi-card.cn/hicardqrcode/qrCode/jsapi/Host6?orderNo=4161801160103314","respCode":"00","organNo":"12999000","respMsg":"处理成功","hicardOrderNo":"4161801160103314"}
            TreeMap<String, String> paramss2 = new TreeMap<String, String>();
            paramss2.put("amount", Long.toString(resJo1.getLong("amount")));
            paramss2.put("createTime", resJo1.getString("createTime"));
            paramss2.put("hicardMerchNo", resJo1.getString("hicardMerchNo"));
            paramss2.put("hicardOrderNo", resJo1.getString("hicardOrderNo"));
            if (resJo1.containsKey("html")) {
                paramss2.put("html", resJo1.getString("html"));
            }
            if (resJo1.containsKey("isT0")) {
                paramss2.put("isT0", resJo1.getString("isT0"));
            }
            paramss2.put("merchOrderNo", resJo1.getString("merchOrderNo"));
            paramss2.put("organNo", resJo1.getString("organNo"));
            paramss2.put("payInfo", resJo1.getString("payInfo"));
            paramss2.put("payType", resJo1.getString("payType"));
            if (resJo1.containsKey("qrURL")) {
                paramss2.put("qrURL", resJo1.getString("qrURL"));
            }
            paramss2.put("respCode", resJo1.getString("respCode"));
            paramss2.put("respMsg", resJo1.getString("respMsg"));
            if (resJo1.containsKey("showPage")) {
                paramss2.put("showPage", resJo1.getString("showPage"));
            }

            paramss2.put("version", resJo1.getString("version"));
            //params2.put("subAppId", resJo.getString("subAppId"));
            String myRSign1 = Safe.sign(paramss2);
            String rSign1 = resJo1.getString("sign");
            Map<String, String> resultMap = new HashMap<>();
		/*if (!myRSign.equals(rSign)) {
			resultMap.put("payState", "fail");
			resultMap.put("message", "签名异常，支付失败!");
			resultMap.put("payUrl", resJo.getString("payInfo"));
		} else {*/
            if ("00".equals(resJo1.getString("respCode"))) {

                String payUrl = resJo1.getString("payInfo");
                JSONObject jsonObject1 =JSONObject.parseObject(payUrl);
                System.out.println("payUrl=======" + payUrl);
                System.out.println("jsonObject1=======" + jsonObject1);
                //map.put("payState", "success");
                //map.put("payUrl", payUrl);
                //map.put("mweb_url", payUrl);
                map.put("status", "WECHAT_PAY");
                OrderExtendDto orderDTO = new OrderExtendDto();
                resultMap.put("appId", jsonObject1.getString("appId"));
                resultMap.put("timeStamp", jsonObject1.getString("timeStamp"));
                resultMap.put("paySign", jsonObject1.getString("paySign"));
                resultMap.put("nonceStr", jsonObject1.getString("nonceStr"));
                resultMap.put("package", jsonObject1.getString("package"));
                resultMap.put("signType", jsonObject1.getString("signType"));
                orderDTO.setJsConfig(resultMap);
                map.put("payMsg", "订单创建成功");
                //map.put("data", resultMap);
                map.put("result", orderDTO);
                System.out.println("payUrl=======" + payUrl);
                // response.sendRedirect(payUrl);
            }
        }else{
            WxPayMpOrderResult result = (WxPayMpOrderResult)weixinPayService
                    .unifyPay(orderSn,param.getFrom(), BillDetailEnum.TYPE_1.getValue(),"公众号充值");
            Map<String,String> config = new HashMap<>();
            config.put("timestamp",result.getTimeStamp());
            config.put("appId",result.getAppId());
            config.put("nonceStr",result.getNonceStr());
            config.put("package",result.getPackageValue());
            config.put("signType",result.getSignType());
            config.put("paySign",result.getPaySign());
            map.put("data",config);
        }




        return ApiResult.ok(map);
    }




}

